<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="eWEdg" id="eWEdg"><span data-lake-id="ubaf21df6" id="ubaf21df6">典型回答</span></h1>
  <p data-lake-id="u301f3cd0" id="u301f3cd0"><br></p>
  <p data-lake-id="u1e65cd72" id="u1e65cd72"><span data-lake-id="u1f9691de" id="u1f9691de">在POI中，提供了SXSSFWorkbook，通过将部分数据写入磁盘上的临时文件来减少内存占用。但是SXSSFWorkbook只能用于文件写入，但是文件读取还是不行的，就像我们前面分析过的，Excel的文件读取还是会存在内存溢出的问题的。</span></p>
  <p data-lake-id="ubdcd69f4" id="ubdcd69f4"><span data-lake-id="u0239ef54" id="u0239ef54">​</span><br></p>
  <p data-lake-id="u6adb2097" id="u6adb2097"><br></p>
  <p data-lake-id="u2e7f347e" id="u2e7f347e"><br></p>
  <p data-lake-id="uff7d5082" id="uff7d5082"><span data-lake-id="u1eddfbe2" id="u1eddfbe2">那如果要解决这个问题，可以考虑使用EasyExcel</span></p>
  <p data-lake-id="u77625c32" id="u77625c32"><span data-lake-id="uf3900634" id="uf3900634">​</span><br></p>
  <blockquote data-lake-id="uab612d8b" id="uab612d8b">
   <p data-lake-id="u241f049d" id="u241f049d"><span data-lake-id="uce8106b6" id="uce8106b6">EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。他能让你在不用考虑性能、内存的等因素的情况下，快速完成Excel的读、写等功能。</span></p>
  </blockquote>
  <p data-lake-id="u78c807b3" id="u78c807b3"><br></p>
  <p data-lake-id="u93bfc1d7" id="u93bfc1d7"><span data-lake-id="u078019b9" id="u078019b9">关于使用XSSFWorkbook和EasyExcel的文件读取，我这里也做了个内存占用的对比：</span></p>
  <p data-lake-id="u186d7f6d" id="u186d7f6d"><span data-lake-id="u05d46b70" id="u05d46b70">​</span><br></p>
  <h3 data-lake-id="ybNe9" id="ybNe9"><span data-lake-id="uaefe1400" id="uaefe1400">XSSFWorkbook文件读取</span></h3>
  <p data-lake-id="u7cbafb68" id="u7cbafb68"><br></p>
  <p data-lake-id="ue8b0bd5e" id="ue8b0bd5e"><span data-lake-id="ud5518753" id="ud5518753">读取一个27.3 MB的文件（文件的生成代码在</span><span data-lake-id="u7b9e03f0" id="u7b9e03f0">中）</span></p>
  <p data-lake-id="u159f9f58" id="u159f9f58"><br></p>
  <pre lang="java"><code>
package excel.read;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class XSSFExcelReadTest {

    public static void main(String[] args) {
        // 指定要读取的文件路径
        String filename = "example.xlsx";

        try (FileInputStream fileInputStream = new FileInputStream(new File(filename))) {
            // 创建工作簿对象
            Workbook workbook = new XSSFWorkbook(fileInputStream);

            // 获取第一个工作表
            Sheet sheet = workbook.getSheetAt(0);

            // 遍历所有行
            for (Row row : sheet) {
                // 遍历所有单元格
                for (Cell cell : row) {
                    // 根据不同数据类型处理数据
                    switch (cell.getCellType()) {
                        case STRING:
                            System.out.print(cell.getStringCellValue() + "\t");
                            break;
                        case NUMERIC:
                            if (DateUtil.isCellDateFormatted(cell)) {
                                System.out.print(cell.getDateCellValue() + "\t");
                            } else {
                                System.out.print(cell.getNumericCellValue() + "\t");
                            }
                            break;
                        case BOOLEAN:
                            System.out.print(cell.getBooleanCellValue() + "\t");
                            break;
                        case FORMULA:
                            System.out.print(cell.getCellFormula() + "\t");
                            break;
                        default:
                            System.out.print(" ");
                    }
                }
                System.out.println();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } 
    }

}

</code></pre>
  <p data-lake-id="u78b29ccd" id="u78b29ccd"><span data-lake-id="ua668e9c9" id="ua668e9c9">​</span><br></p>
  <p data-lake-id="u18eeed0b" id="u18eeed0b"><span data-lake-id="u82130102" id="u82130102">​</span><br></p>
  <p data-lake-id="uedbf9a93" id="uedbf9a93"><span data-lake-id="uded80c93" id="uded80c93">同样使用Arthas查看内存占用情况：</span></p>
  <p data-lake-id="ua23bdbc0" id="ua23bdbc0"><span data-lake-id="u5362eb45" id="u5362eb45">​</span><br></p>
  <p data-lake-id="u6654aa6a" id="u6654aa6a"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1700377615322-53e7546e-3383-4316-8506-16eada7b74e5.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_65%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="u53f4dda0" id="u53f4dda0"><span data-lake-id="ucab07cda" id="ucab07cda">​</span><br></p>
  <p data-lake-id="u4900bfe5" id="u4900bfe5"><span data-lake-id="ub8531a24" id="ub8531a24">占用内存在1000+M。</span></p>
  <p data-lake-id="ufcd2353a" id="ufcd2353a"><span data-lake-id="u2bb0b6b0" id="u2bb0b6b0">​</span><br></p>
  <h3 data-lake-id="OfD1a" id="OfD1a"><span data-lake-id="u9b15fd0f" id="u9b15fd0f">EasyExcel文件读取</span></h3>
  <pre lang="java"><code>
package excel.read;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;

public class EasyExcelReadTest {

    public static void main(String[] args) {
        // 指定要读取的文件路径
        String filename = "example.xlsx";

        EasyExcel.read(filename, new PrintDataListener()).sheet().doRead();
    }

}

// 监听器，用于处理读取到的数据
class PrintDataListener implements ReadListener&lt;Object&gt; {
    @Override
    public void invoke(Object data, AnalysisContext context) {
        // 处理每一行的数据
        System.out.println(data);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 所有数据解析完成后的操作
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        // 处理读取过程中的异常
    }
}
</code></pre>
  <p data-lake-id="u30cf2b02" id="u30cf2b02"><br></p>
  <p data-lake-id="uc0597b8e" id="uc0597b8e"><span data-lake-id="ub9042c60" id="ub9042c60">同样使用Arthas查看内存占用情况：</span></p>
  <h3 data-lake-id="YfLQn" id="YfLQn"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1700377694873-6495aa8e-f41e-4842-8e03-0c6848a6c6b4.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_65%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"><span data-lake-id="u0373c473" id="u0373c473"></span></h3>
  <p data-lake-id="u5860671d" id="u5860671d"><br></p>
  <p data-lake-id="uaa68a02a" id="uaa68a02a"><span data-lake-id="u8c764b7a" id="u8c764b7a">内存占用只有不到100M。</span></p>
  <p data-lake-id="ua4dc8a03" id="ua4dc8a03"><span data-lake-id="u2f079f05" id="u2f079f05">​</span><br></p>
  <h1 data-lake-id="KjjET" id="KjjET"><span data-lake-id="u67c8c6e9" id="u67c8c6e9">扩展知识</span></h1>
  <p data-lake-id="u69765931" id="u69765931"><br></p>
  <h2 data-lake-id="s8vDw" id="s8vDw"><span data-lake-id="uc36475f6" id="uc36475f6">EasyExcel为啥内存占用小</span></h2>
  <p data-lake-id="uef4d23ed" id="uef4d23ed"><br></p>
  <p data-lake-id="uc3340098" id="uc3340098"><span data-lake-id="u6e19e8d2" id="u6e19e8d2">占坑，后面单独写一篇文章。</span></p>
 </body>
</html>